package com.keqiang.chart.impl.axis.impl.pseudo3d.bar

import android.graphics.Canvas
import android.graphics.Paint
import android.text.TextPaint
import com.keqiang.chart.impl.axis.render.XAxisRender
import com.keqiang.chart.utils.ObjectPool
import com.keqiang.chart.utils.draw3DRectangle
import com.keqiang.chart.utils.toRadian
import kotlin.math.cos
import kotlin.math.sin

/**
 * 柱状图X轴绘制器
 *
 * @author Created by wanggaowan on 2022/8/11 11:23
 */
open class Bar3DXAxisRender constructor(chart: BarChart3D) : XAxisRender<BarChart3D>(chart, false) {

    override fun onDraw(canvas: Canvas, start: Float, top: Float, end: Float, bottom: Float,
                        gridWidth: Float, labelMaxHeight: Float, yAxisRange: Float) {

        val textPaint = ObjectPool.obtainPaint<TextPaint>(true)
        val paint = ObjectPool.obtainPaint<Paint>()
        val tempRectF = ObjectPool.obtainRectF()
        val path = ObjectPool.obtainPath()

        // 绘制轴线
        val xAxis = chart.xAxis
        val yAxis = chart.yAxis
        canvas.draw3DRectangle(paint, start, bottom, end - start, xAxis.lineWidth,
            xAxis.lineHeight, xAxis.lineColor, chart.faceDegrees)

        val faceRadian = chart.faceDegrees.toRadian
        val yOffset = sin(faceRadian) * xAxis.lineWidth
        xAxis.drawRectF.set(start, top - yOffset, end, bottom)

        // 绘制轴线文本
        var tempStart = start + xAxis.startPadding
        textPaint.textSize = xAxis.labelTextSize
        textPaint.color = xAxis.labelColor
        setPaint(paint, xAxis.gridLineColor, xAxis.gridLineWidth, xAxis.gridLinePathEffect)

        xAxis.labelList?.let {
            for (index in it.indices) {
                if (gridWidth > 0 && labelMaxHeight > 0) {
                    if (drawLabelByGridLine) {
                        drawLabelByGridLine(canvas, textPaint, index, it, xAxis, gridWidth, bottom, end,
                            labelMaxHeight, tempStart, tempRectF)
                    } else {
                        drawLabelByGridCenter(canvas, textPaint, index, it, xAxis, gridWidth, bottom,
                            labelMaxHeight, tempStart, tempRectF)
                    }
                }

                if (index > 0 && xAxis.drawGridLine) {
                    // 绘制X轴网格线
                    val x = tempStart + cos(faceRadian) * xAxis.lineWidth
                    val yEnd = top - yOffset
                    val yTop =
                        if (xAxis.gridUseEndPadding) yEnd - yAxisRange + yAxis.endPadding else yEnd - yAxisRange

                    path.reset()
                    path.moveTo(x, yTop)
                    path.lineTo(x, if (xAxis.gridUseStartPadding) yEnd - yAxis.startPadding else yEnd)
                    canvas.drawPath(path, paint)
                }

                tempStart += gridWidth
            }

            if (xAxis.drawGridLine && it.isNotEmpty()) {
                // 绘制X轴网格线
                val x = tempStart + cos(faceRadian) * xAxis.lineWidth

                val yEnd = top - yOffset
                val yTop =
                    if (xAxis.gridUseEndPadding) yEnd - yAxisRange + yAxis.endPadding else yEnd - yAxisRange
                path.reset()
                path.moveTo(x, yTop)
                path.lineTo(x, if (xAxis.gridUseStartPadding) yEnd - yAxis.startPadding else yEnd)
                canvas.drawPath(path, paint)
            }
        }

        ObjectPool.recycleRectF(tempRectF)
        ObjectPool.recyclePaint(paint)
        ObjectPool.recyclePaint(textPaint)
        ObjectPool.recyclePath(path)
    }
}